Skip to content

Conversation

@Clee2691
Copy link
Contributor

@Clee2691 Clee2691 commented Nov 3, 2025

Description

This PR fixes an issue where Vector collectors cannot access log stores outside the cluster when both restrictive network policies are enabled and the cluster has a cluster-wide proxy configured.

CLO will attempt to parse the port from the proxy URLS based on the proxy variables:

  • HTTP_PROXY
  • HTTPS_PROXY

If the port is not specified for the proxy URL, it will add the default ports for the specific schema

  • HTTP: 80
  • HTTPS: 443

/cc @cahartma @vparfonov
/assign @jcantrill

Links

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Nov 3, 2025
@openshift-ci-robot
Copy link

openshift-ci-robot commented Nov 3, 2025

@Clee2691: This pull request references LOG-8068 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the bug to target the "4.8.0" version, but no target version was set.

In response to this:

Description

This PR fixes an issue where Vector collectors cannot access log stores outside the cluster when both restrictive network policies are enabled and the cluster has a cluster-wide proxy configured.

CLO will attempt to parse the port from the proxy URLS based on the proxy variables:

  • HTTP_PROXY
  • HTTPS_PROXY

If the port is not specified for the proxy URL, it will add the default ports for the specific schema

  • HTTP: 80
  • HTTPS: 443

/cc @cahartma @vparfonov
/assign @jcantrill

Links

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci bot requested review from cahartma and vparfonov November 3, 2025 17:32
@Clee2691
Copy link
Contributor Author

Clee2691 commented Nov 3, 2025

/retest

for _, envVar := range proxyEnvVars {
// Process proxy environment variables
if proxyEnvNames.Has(envVar.Name) {
if port := parsePortProtocolFromURL(envVar.Value); port != nil {
Copy link
Contributor

@cahartma cahartma Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

corrected:
In the case where the parseUrl fails, it will end up running url.Parse() twice .
maybe the line above could be changed to something like:
if (envVar.Name == "http_proxy" || envVar.Name == "https_proxy") && envVar.Value != "" {
in that case you wouldn't need to create the set and the extra nested if. lmk if you want to chat.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a set here so that I can handle the different cases for the environment variable names.
I have consolidated this however so that url.Parse is not called twice.

Copy link
Contributor

@cahartma cahartma Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm good with this as is, since it works. But there are still a few steps that are unnecessary. GetProxyEnvVars() returns strings.ToLower(envvar) so you've already evaluated both cases.
Additionally, there are several different if statements nested inside a loop, which is always best to avoid if possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. I was able to reduce the nesting of the if statements along with removing the set since the names are lowered already.

} else if envVar.Value != "" {
// If no explicit port, add default port based on scheme
if parsedURL, err := url.Parse(envVar.Value); err == nil {
var defaultPort int32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would have thought you can use getDefaultPort() here?

Copy link
Contributor

@cahartma cahartma Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

otherwise, I would create a quick helper below this: getProxyDefaultPort(scheme) to help clean up the many nested possibilities.
you could return a boolean so you don't have to run the final if > 0. To use the helper, my suggestion would be to simplify the final check:
defaultPort, ok := getProxyDefaultPort(parsedURL.Scheme); ok { portProtocolMap[....] = true }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getDefaultPort() is for the outputs which I guess a better name would have been getOutputDefaultPort().

Good suggestion. I will add in the helper.

BeforeEach(func() {
// Save original environment variables
originalEnvVars = make(map[string]string)
for _, envVar := range []string{"HTTP_PROXY", "HTTPS_PROXY", "http_proxy", "https_proxy", "NO_PROXY", "no_proxy"} {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use util.GetProxyEnvVars() here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work because if there are no proxy environment variables, originalEnvVars won't be populated and the unsetting/setting of the environment variables will not work properly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. For future, we should probably use a constant if possible, since we are evaluating the same slice in a couple places.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in a constant for this and updated the code accordingly.

@jcantrill
Copy link
Contributor

/hold

@openshift-ci openshift-ci bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Nov 4, 2025
Copy link
Contributor

@jcantrill jcantrill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/approve

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Nov 4, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Clee2691, jcantrill

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Nov 4, 2025
}
},
Entry("should extract ports from HTTP proxy URLs with explicit ports",
map[string]string{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are making changes, since we need so many iterations/entries, I have a suggestion for cleaning up by using a couple helper functions:

Something like this:
setProxies("http://proxy.example.com:8080", "https://proxy.example.com:8443"),
and for the protocol:
expectedProxyPorts(8080, 8443), (all are TCP, so this can be removed?)

func setProxies(httpProxy string, httpsProxy string) map[string]string {}
func expectedProxyPorts(ports ...int32) []factory.PortProtocol {}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

untested:

expectd := make([]factory.PortProtocol, 0, len(ports))
for _, port := range ports {
	expected = append(expected, factory.PortProtocol{
			Port:     port,
			Protocol: corev1.ProtocolTCP, 
	})
}
return expected

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestions. Added into the tests.

…trict network policy is enabled and the cluster has cluster-wide proxy.
@cahartma
Copy link
Contributor

cahartma commented Nov 4, 2025

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Nov 4, 2025
@Clee2691
Copy link
Contributor Author

Clee2691 commented Nov 4, 2025

/hold cancel

@openshift-ci openshift-ci bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Nov 4, 2025
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Nov 4, 2025

@Clee2691: all tests passed!

Full PR test history. Your PR dashboard.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@openshift-merge-bot openshift-merge-bot bot merged commit e44d361 into openshift:master Nov 4, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged. release/6.4

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants